package com.bdth.controller;

import com.bdth.model.*;
import com.bdth.service.IAlarmConfigService;
import com.bdth.service.IAlarmService;
import com.bdth.service.IDepartmentService;
import com.bdth.service.IDeviceService;
import com.bdth.utils.*;
import com.bdth.utils.DateUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;

@Controller
@RequestMapping("/alarm")
public class AlarmController extends BaseController {

	@Autowired
	private IAlarmService alarmService;

	@Autowired
	private IAlarmConfigService alarmConfigService;

	@Autowired
	private IDeviceService deviceService;

	@Autowired
	private IDepartmentService departmentService;

	private static String KEY_ALARM_MAP = "key_alarm_map";

	protected static final Logger logger = LoggerFactory.getLogger(AlarmController.class);

	/**
	 * json 列表页面
	 *
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/dataListForMain")
	public void dataListForMain(PageModel pageModel, HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		Map<String, Object> map = new HashMap<String, Object>();
		String equipName = request.getParameter("equipName");
		String simNo = request.getParameter("simNo");
		String alarmType = request.getParameter("alarmType");
		String alarmSource = request.getParameter("alarmSource");
		String startTime = "" + request.getParameter("startTime");
		String endTime = "" + request.getParameter("endTime");
		if (StringUtil.isEmptyWithNullStr(startTime)) {
			startTime = DateUtil.convertDateToYearMonthDay(new Date());
			endTime = DateUtil.convertDateToYearMonthDay(new Date());
		} else {
			startTime = startTime.substring(0, 10).replace("-", "");
			endTime = endTime.substring(0, 10).replace("-", "");
		}
		String today = DateUtil.getFomartDate(new Date(), "yyyyMMdd");
		if (endTime.compareTo(today) > 0)
			endTime = today;
		map.put("simNo", simNo);
		map.put("equipName", equipName);
		String tableName1 = "tb_HisAlarm" + startTime;
		map.put("tableName1", tableName1);

		map.put("startTime", DateUtil.getFomartDate(new Date(new Date().getTime() - 600000), "yyyy-MM-dd HH:mm:ss"));
		map.put("endTime", DateUtil.getFomartDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
		map.put("alarmType", alarmType);
		map.put("alarmSource", alarmSource);
		map.put("processed", 0);
		User user = SessionUtils.getUser(request);
		if (user == null) {
			String path = request.getContextPath();
			response.sendRedirect(path + "/login");
		}
		List<Integer> depIds = getDepIds(user.getDepId());
		map.put("depIds", depIds);
		//紧跟着的第一个查询方法会被分页
		PageHelper.startPage(pageModel.getPage(), pageModel.getRows());
		List<Map> dataList = alarmService.queryMapDataByMapList(map);

		for (Map map1 : dataList) {
			Map mapAlarm = new HashMap();
			mapAlarm.put("alarmSource", map1.get("alarmSource"));
			mapAlarm.put("alarmType", "" + map1.get("alarmType"));
			AlarmConfig ac = alarmConfigService.queryByAlarmSourceAndAlarmType(mapAlarm);
			if (ac != null) {
				map1.put("alarmType", ac.getName());
			}
		}

		//获得结果集条总数
		PageInfo pageList = new PageInfo(dataList);
		//设置页面数据
		Map<String, Object> jsonMap = new HashMap<String, Object>();
		jsonMap.put("total", pageList.getTotal());
		jsonMap.put("rows", dataList);
		HtmlUtil.writerJson(response, jsonMap);
	}


	// 将报警数据发给页面弹窗显示
	@RequestMapping("/alarm")
	public void alarm(HttpServletRequest request, HttpServletResponse response) {
		Map<String, Object> context = new HashMap<String, Object>();
		Hashtable alarmData = new Hashtable();
		try {
			Hashtable parameters = new Hashtable();
			String tableName = "tb_HisAlarm"
					+ DateUtil.getFomartDate(new Date(), "yyyyMMdd");
			parameters.put("tableName1", tableName);// 报警数据是一个月一张表
			parameters.put("startTime", DateUtil.getFomartDate(new Date(new Date().getTime() - 600000), "yyyy-MM-dd HH:mm:ss"));
			parameters.put("endTime", DateUtil.getFomartDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
			User user = SessionUtils.getUser(request);
			if (user == null) {
				String path = request.getContextPath();
				response.sendRedirect(path + "/login");
			}
			List<Integer> depIds = getDepIds(user.getDepId());
			parameters.put("depIds", depIds);
			parameters.put("dataListForExport", true);
			try {
				List result = alarmService.queryMapDataByMapList(parameters);
				result = filterAlarmResult(result, request, depIds);
				alarmData.put("alarm", result);
			} catch (Exception ex) {
				logger.error(ex.getMessage(), ex);
			}
			context.put(SUCCESS, true);
			context.put("data", alarmData);

			HtmlUtil.writerJson(response, context);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
	}


	/**
	 * 已经报警的，将不再重复弹出
	 *
	 * @param alarmList
	 * @return
	 */

	private List filterAlarmResult(List alarmList, HttpServletRequest request, List depIds) throws Exception {
		Map<String, Date> alarmMap = getAlarmMap(request);
		List result = new ArrayList();
		for (Object obj : alarmList) {
			Map rowData = (Map) obj;
			int alarmId = (int) rowData.get("id");
			int depId = (int) rowData.get("depId");
			// 车辆不是用户所管辖的单位
			if (isAuthorizedDep(depId, request, depIds) == false)
				continue;

			String key = "_" + alarmId;
			// 只推送未推送的报警，已经推送到前台的，不再推送。
			if (alarmMap.containsKey(key) == false) {
				alarmMap.put(key, new Date());
				// 查看该类型的报警，数据库中是否配置
				String alarmType = "" + rowData.get("alarmType");
				String alarmSource = "" + rowData.get("alarmSource");
				Map map = new HashMap();
				map.put("alarmSource", alarmSource);
				map.put("alarmType", alarmType);
				AlarmConfig ac = alarmConfigService.queryByAlarmSourceAndAlarmType(map);
				if (ac != null && ac.getEnabled()) {
					// 报警声音的开关配置在meta属性中.
					rowData.put("soundEnabled", (Boolean) ac.getSoundEnabled());
					rowData.put("popupEnabled", (Boolean) ac.getPopupEnabled());
					String alarmTypeDescr = ac.getName();
					//if (ac.getAlarmType() == AlarmRecord.TYPE_IN_AREA || ac.getAlarmType() == AlarmRecord.TYPE_CROSS_BORDER) {
					//alarmTypeDescr += "," + rowData.get("location");
					//}
					rowData.put("alarmTypeDescr", alarmTypeDescr);
					//convert(rowData);
					result.add(rowData);

				}

			}

		}
		//System.out.println(result);
		return result;
	}


	/**
	 * 已经报警的记录，保存在Session中，避免重复报警
	 *
	 * @return
	 */
	public Map<String, Date> getAlarmMap(HttpServletRequest request) {
		Map<String, Date> alarmMap = (HashMap<String, Date>) request.getSession(true).getAttribute(
				KEY_ALARM_MAP);
		if (alarmMap == null) {
			alarmMap = new HashMap<String, Date>();
			request.getSession(true).setAttribute(KEY_ALARM_MAP, alarmMap);
		}
		return alarmMap;
	}

	protected boolean isAuthorizedDep(int depId, HttpServletRequest request, List depIds) throws Exception {
		if (depIds.contains(depId)) {
			return true;
		} else {
			return false;
		}
	}


	private void convert(Map rowData) {

		// 报警来源
		//rowData.put("alarmsource", convert(rowData, "alarmSource", "AlarmSource"));
		//rowData.put("processed", convert(rowData, "processed", "ProcessType"));
		try {
			String simNo = "" + rowData.get("simNo");
			Device c = deviceService.queryBySimNo(simNo);
			Department department = null;
			if (c != null) {

				department = departmentService.queryById(c.getDepId());

			}
			rowData.put("startTime", "" + rowData.get("startTime"));
			String depName = "";
			if (department != null)
				depName = department.getDepName();
			rowData.put("depName", depName);
		} catch (Exception e) {
			e.printStackTrace();
		}


	}


	/**
	 * json 列表页面
	 *
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/dataList")
	public void dataList(PageModel pageModel, HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		List dataList = getDataList(pageModel, request, true);
		for (Object obj : dataList) {
			Map mapAlarm = new HashMap();
			Map map1 = (Map) obj;
			mapAlarm.put("alarmSource", map1.get("alarmSource"));
			mapAlarm.put("alarmType", "" + map1.get("alarmType"));
			AlarmConfig ac = alarmConfigService.queryByAlarmSourceAndAlarmType(mapAlarm);
			if (ac != null) {
				map1.put("alarmType", ac.getName());
			}
			double longitude = Double.parseDouble("" + map1.get("longitude"));
			double latitude = Double.parseDouble("" + map1.get("latitude"));
			map1.put("orgLatitude", latitude);
			map1.put("orgLongitude", longitude);
			PointLatLng pt = MapFixService.fix(latitude, longitude,
					Constants.MAP_BAIDU);
			map1.put("longitude", pt.getLng());
			map1.put("latitude", pt.getLat());
		}

		//获得结果集条总数
		PageInfo pageList = new PageInfo(dataList);
		//设置页面数据
		Map<String, Object> jsonMap = new HashMap<String, Object>();
		jsonMap.put("total", pageList.getTotal());
		jsonMap.put("rows", dataList);
		HtmlUtil.writerJson(response, jsonMap);
	}

	@RequestMapping("/viewAlarm")
	public ModelAndView viewAlarm(int alarmId, String createDate, HttpServletRequest request, HttpServletResponse response) {
		HisAlarm alarm = new HisAlarm();
		Map<String, Object> context = getRootMap();
		try {
			alarm = this.getAlarm(alarmId, createDate, request, response);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		}
		context.put("alarm", alarm);
		context.put("alarmId", alarm.getId());
		context.put("alarmDate", createDate);
		Device device = deviceService.queryBySimNo(alarm.getSimNo());
		if (device != null) {
			context.put("equipName", device.getEquipName());
		}
		String alarmType = "" + alarm.getAlarmType();
		String alarmSource = "" + alarm.getAlarmSource();
		Map map = new HashMap();
		map.put("alarmSource", alarmSource);
		map.put("alarmType", alarmType);
		AlarmConfig ac = alarmConfigService.queryByAlarmSourceAndAlarmType(map);
		if (ac != null) {
			context.put("alarmTypeDesc", ac.getName());
		}
		if ("terminal".equals(alarmSource)) {
			context.put("alarmSourceDesc", "终端报警");
		}
		if ("platform".equals(alarmSource)) {
			context.put("alarmSourceDesc", "平台报警");
		}
		return forword("/alarm/processAlarm", context);
	}

	private HisAlarm getAlarm(int alarmId, String createDate, HttpServletRequest request, HttpServletResponse response) throws Exception {

		Hashtable parameters = new Hashtable();
		if (!StringUtil.isEmptyWithNullStr(createDate)) {
			createDate = createDate.substring(0, 10).replace("-", "");
		}
		String tableName = "tb_HisAlarm" + createDate;
		parameters.put("tableName1", tableName);// 报警数据是一天一张表
		parameters.put("alarmId", alarmId);
		User user = SessionUtils.getUser(request);
		if (user == null) {
			String path = request.getContextPath();
			response.sendRedirect(path + "/login");
		}
		List<Integer> depIds = getDepIds(user.getDepId());
		parameters.put("depIds", depIds);
		List<Map> result = alarmService.queryMapDataByMapList(parameters);
		//result = filterAlarmResult(result);
		HisAlarm alarm = new HisAlarm();
		// alarmData.Add("alarm", result);
		if (result != null && result.size() > 0) {
			Map a = (Map) result.get(0);

			this.convert(a);
			alarm.setId((int) a.get("id"));

			alarm.setSimNo("" + a.get("simNo"));
			alarm.setAlarmType((int) a.get("alarmType"));
			alarm.setAlarmSource("" + a.get("alarmSource"));
/*			if (a.get("remark") != null)
				alarm.setRemark("" + a.get("remark"));
			else
				alarm.setRemark("已处理");*/
			alarm.setAlarmTime(DateUtil.getDateFromString("" + a.get("alarmTime")));
		}

		return alarm;
	}


	/**
	 * 报警处理
	 *
	 * @return
	 */
	@RequestMapping("/process")
	public void process(int alarmId, String alarmDate, HttpServletRequest request, HttpServletResponse response) throws Exception {
		boolean flag = true;
		try {


			HisAlarm alarm = this.getAlarm(alarmId, alarmDate, request, response);

			User user = SessionUtils.getUser(request);
			//this.BaseService.saveOrUpdate(alarm);
			if (!StringUtil.isEmptyWithNullStr(alarmDate)) {
				alarmDate = alarmDate.substring(0, 10).replace("-", "");
			}
			String tableName = "tb_HisAlarm" + alarmDate;
			Map map = new HashMap();
			map.put("tableName1", tableName);
			map.put("processed", 1);
			map.put("processedTime", new Date());
			map.put("id", alarmId);
			if (user != null) {
				map.put("processedUserId", user.getId());
			}
			alarmService.updateHisAlarm(map);

			sendSuccessMessage(response, "报警处理成功");
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		}

	}


	public List getDataList(PageModel pageModel, HttpServletRequest request, boolean pageFlag) throws Exception {
		Map<String, Object> map = new HashMap<String, Object>();
		List<Map> dataList = null;
		String equipName = request.getParameter("equipName");
		String simNo = request.getParameter("simNo");
		String startTime = "" + request.getParameter("startTime");
		String endTime = "" + request.getParameter("endTime");
		String dataListForExport = request.getParameter("dataListForExport");
		if (StringUtil.isEmptyWithNullStr(startTime)) {
			startTime = DateUtil.convertDateToYearMonthDay(new Date());
			endTime = DateUtil.convertDateToYearMonthDay(new Date());
		} else {
			startTime = startTime.substring(0, 10).replace("-", "");
			endTime = endTime.substring(0, 10).replace("-", "");
		}
		String today = DateUtil.getFomartDate(new Date(), "yyyyMMdd");
		if (endTime.compareTo(today) > 0)
			endTime = today;
		map.put("simNo", simNo);

		String tableName1 = "tb_HisAlarm" + startTime;
		String tableName2 = "tb_HisAlarm" + endTime;
		map.put("tableName1", tableName1);
		map.put("tableName2", tableName2);

		map.put("startTime", request.getParameter("startTime"));
		map.put("endTime", request.getParameter("endTime"));
		map.put("alarmType", "");
		map.put("alarmSource", "");
		map.put("equipName", equipName);
		User user = SessionUtils.getUser(request);
		List<Integer> depIds = getDepIds(user.getDepId());
		map.put("depIds", depIds);
		map.put("dataListForExport", dataListForExport);
		if (pageFlag) {
			//紧跟着的第一个查询方法会被分页
			PageHelper.startPage(pageModel.getPage(), pageModel.getRows());
		}
		if (tableName1.equals(tableName2) == false) {
			dataList = alarmService.queryMapDataByMapListIn2Months(map);
		} else {
			dataList = alarmService.queryMapDataByMapList(map);
		}
		return dataList;
	}


	/**
	 * 导出历史数据
	 *
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = "/exportHisAlarm")
	public void exportHisAlarm(HttpServletRequest request, HttpServletResponse response) throws Exception {
		try {
			List dataList = getDataList(null, request, false);
			String equipName = request.getParameter("equipName");
			String simNo = request.getParameter("simNo");

			String separator = File.separator;
			String xlsFile = System.getProperty("csc2.root") + separator
					+ "excel" + separator
					+ "hisAlarmModel.xlsx";
			String filename = "报警数据.xlsx";// 设置下载时客户端Excel的名称
			OutputStream ouputStream = null;
			Workbook workbook = WorkbookFactory.create(new FileInputStream(xlsFile));
			Sheet sheet = workbook.getSheetAt(0);
			Font headerFont = workbook.createFont(); // 字体
			headerFont.setFontHeightInPoints((short) 11);
			headerFont.setFontName("Arial");
			int count = 0;
			// 设置数据行

			Row row1 = sheet.getRow(0);
			Cell cell1 = row1.getCell(1);
			cell1.setCellValue(equipName);
			Cell cell2 = row1.getCell(3);
			cell2.setCellValue(simNo);
			Row row2 = sheet.getRow(1);
			Cell cell3 = row2.getCell(1);
			cell3.setCellValue(request.getParameter("startTime"));
			Cell cell4 = row2.getCell(3);
			cell4.setCellValue(request.getParameter("endTime"));
			CellStyle cellStyle = workbook.createCellStyle();

			cellStyle.setAlignment(XSSFCellStyle.ALIGN_LEFT);


			cellStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER); // 水平布局：居中
			cellStyle.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
			cellStyle.setBorderBottom(XSSFCellStyle.BORDER_THIN);
			cellStyle.setBottomBorderColor(new XSSFColor(java.awt.Color.BLACK).getIndexed());
			cellStyle.setBorderLeft(XSSFCellStyle.BORDER_THIN);
			cellStyle.setLeftBorderColor(new XSSFColor(java.awt.Color.BLACK).getIndexed());
			cellStyle.setBorderRight(XSSFCellStyle.BORDER_THIN);
			cellStyle.setRightBorderColor(new XSSFColor(java.awt.Color.BLACK).getIndexed());
			cellStyle.setBorderTop(XSSFCellStyle.BORDER_THIN);
			cellStyle.setTopBorderColor(new XSSFColor(java.awt.Color.BLACK).getIndexed());
			cellStyle.setFont(headerFont);
			cellStyle.setWrapText(true);

			int i = 0;
			for (Object obj : dataList) {
				Map r = (Map) obj;
				try {
					Map mapAlarm = new HashMap();
					mapAlarm.put("alarmSource", r.get("alarmSource"));
					mapAlarm.put("alarmType", "" + r.get("alarmType"));
					AlarmConfig ac = alarmConfigService.queryByAlarmSourceAndAlarmType(mapAlarm);
					String alarmSource = "";
					if ("terminal".equals(r.get("alarmSource"))) {
						alarmSource = "终端报警";
					}
					if ("platform".equals(r.get("alarmSource"))) {
						alarmSource = "平台报警";
					}
					Object[] data = {r.get("equipName") + "",
							r.get("simNo") + "",
							r.get("depName") + "",
							ac.getName() + "",
							alarmSource,
							DateUtil.getPlusTime(DateUtil.getDateFromString(r.get("alarmTime") + "")),
							r.get("longitude") + "",
							r.get("latitude") + "",
							r.get("speed") + ""};
					ExportExcelUtil.writeRowLine(workbook,
							sheet, cellStyle,
							headerFont,
							i + 3,
							data);
					i++;
				} catch (Exception e) {
					logger.error(e.getMessage());
					continue;
				}
			}


			filename = ExportExcelUtil.encodeFilename(filename, request);
			response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
			response.addHeader("Content-Disposition", "attachment;filename=" + filename);
			ouputStream = response.getOutputStream();
			workbook.write(ouputStream);
			ouputStream.flush();
			ouputStream.close();

		} catch (IOException e) {
			logger.error(e.getMessage());
		} catch (Exception e) {
			logger.error(e.getMessage());
		}

	}
}
